﻿// <copyright>
// Project: sofort.NET
// Date:  2014 - 02 - 04
// Copyright: Karl Haak 2014
// </copyright>
// <author>Karl Haak (www.karlhaak.de)</author>
namespace pay.sofort
{
    using System;
    using System.IO;
    using System.Net;
    using System.Reflection;
    using System.Text;
    using System.Xml.Linq;
    using Models;
    
    public class TPaySofortMultipayManager
    {
        #region ### Member ###

        private readonly TPaySofortConfig Config;
        private readonly PaySofortContext Context;

        #endregion

        #region ### Ctor ###

        public TPaySofortMultipayManager(TPaySofortConfig config)
        {
            Config = config;
            Context = new PaySofortContext(config.ConnectionString, config.Username);
        }

        #endregion

        #region ### Private ###

        private PaySofortOut CreateOutLog(PaySofortMultipay multipay)
        {
            XDocument xDocument = TPaySofortXml.CreateXDocumentMultipay(multipay);
            string xmlText = xDocument.Declaration + Environment.NewLine + xDocument;

            PaySofortOut outLog = new PaySofortOut
            {
                RefGuid = multipay.PaySofortMultipayGuid,
                ApiKey = Config.ApiKey,
                Kundennummer = Config.Kundennummer,
                ProjectId = Config.ProjectId,
                Url = Config.SofortUeberweisungUrl,
                Typ = "Multipay",
                PayloadOut = xmlText
            }.SetNew(Config.Username);

            Context.PaySofortOut.Add(outLog);
            Context.SaveChanges();

            return outLog;
        }

        private string RunWebRequestProvider(PaySofortOut outLog)
        {
            // Header
            var Request = (HttpWebRequest) WebRequest.Create(Config.SofortUeberweisungUrl);
            Request.Method = "POST";
            Request.Credentials = new NetworkCredential(Config.Kundennummer, Config.ApiKey);
            Request.ContentType = "application/xml";
            Request.Accept = "application/xml; charset=UTF-8";

            // Set Payload
            byte[] requestBytes = new UTF8Encoding().GetBytes(outLog.PayloadOut);
            Stream stream = Request.GetRequestStream();
            stream.Write(requestBytes, 0, requestBytes.Length);
            stream.Close();

            // Read Response
            try
            {
                var response = (HttpWebResponse) Request.GetResponse();
                Stream responseStream = response.GetResponseStream();

                var sr = new StreamReader(responseStream);
                string responsePayload = sr.ReadToEnd();
                outLog.HttpStatus = response.StatusCode.ToString();
                outLog.PayloadIn = responsePayload;
                Context.SaveChanges();
                return responsePayload;
            }
            catch (Exception ex)
            {
                outLog.PayloadOut = ex.Message;
                Context.SaveChanges();
                throw;
            }
        }

        private PaySofortNewTransaction CreatePaySofortNewTransaction(string xmlIn)
        {
            PaySofortNewTransaction newTransaction = TPaySofortXml.CreatePaySofortNewTransaction(xmlIn, Config.Username);
            Context.PaySofortNewTransaction.Add(newTransaction);
            Context.SaveChanges();
            return newTransaction;
        }

        #endregion

        #region ### Public ###

        public PaySofortNewTransaction SendMultipay(PaySofortMultipay paySofortMultipay)
        {
            Context.PaySofortMultipay.Add(paySofortMultipay);
            Context.SaveChanges();

            PaySofortOut outLog = CreateOutLog(paySofortMultipay);

            string xmlIn = RunWebRequestProvider(outLog);

            PaySofortNewTransaction newTransaction = CreatePaySofortNewTransaction(xmlIn);

            return newTransaction;
        }

        public PaySofortMultipay CreateMultipaySimple(decimal amount)
        {
            PaySofortMultipay paySofortMultipay = new PaySofortMultipay
            {
                PaySofortMultipayGuid = Guid.NewGuid(),
                interface_version = "Sofort.NET " + Assembly.GetExecutingAssembly().GetName().Version,
                language_code = "de",
                project_id = Config.ProjectId,
                amount = amount,
                currency_code = "EUR",
            }.SetNew(Config.Username);

            if (!String.IsNullOrWhiteSpace(Config.SuccessUrl)) paySofortMultipay.success_url = Config.SuccessUrl;
            if (!String.IsNullOrWhiteSpace(Config.TimeoutUrl)) paySofortMultipay.timeout_url = Config.TimeoutUrl;
            if (!String.IsNullOrWhiteSpace(Config.AbortUrl)) paySofortMultipay.abort_url = Config.AbortUrl;

            if (!String.IsNullOrWhiteSpace(Config.Notification_url_1))
                paySofortMultipay.notification_url_1 = Config.Notification_url_1;
            if (!String.IsNullOrWhiteSpace(Config.Notification_url_2))
                paySofortMultipay.notification_url_2 = Config.Notification_url_2;
            if (!String.IsNullOrWhiteSpace(Config.Notification_url_1_notify_on))
                paySofortMultipay.notification_url_1_notify_on = Config.Notification_url_1_notify_on;
            if (!String.IsNullOrWhiteSpace(Config.Notification_url_2_notify_on))
                paySofortMultipay.notification_url_2_notify_on = Config.Notification_url_2_notify_on;

            return paySofortMultipay;
        }

        #endregion
    }
}